package com.reebake.ideal.mybatis.core;

import cn.hutool.core.util.ObjUtil;
import com.fasterxml.jackson.core.JacksonException;
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.*;
import com.fasterxml.jackson.databind.node.ObjectNode;
import com.reebake.ideal.mybatis.properties.PaginationProperties;

import java.io.IOException;

public class PageResultDeserializer extends JsonDeserializer<PageResult<?>> {
    private PaginationProperties paginationProperties;
    private ObjectMapper objectMapper;

    public PageResultDeserializer(ObjectMapper objectMapper, PaginationProperties paginationProperties) {
        this.paginationProperties = paginationProperties;
        this.objectMapper = objectMapper;
    }

    @Override
    public PageResult<?> deserialize(JsonParser p, DeserializationContext ctxt) throws IOException, JacksonException {
        JsonNode root = p.readValueAsTree();
        if (ObjUtil.isNull(root) || !root.isObject()) {
            return null;
        }
        ObjectNode rootObjectNode = (ObjectNode) root;
        String pageNumberAttr = paginationProperties.getPageNumberParameterName();
        JsonNode pageNumberNode = root.get(pageNumberAttr);
        String currentName = "current";
        if (!currentName.equals(pageNumberAttr)) {
            rootObjectNode.set(currentName, pageNumberNode);
            rootObjectNode.remove(pageNumberAttr);
        }
        String pageSizeAttr = paginationProperties.getPageSizeParameterName();
        JsonNode pageSizeNode = root.get(pageSizeAttr);
        String sizeName = "size";
        if (!sizeName.equals(pageSizeAttr)) {
            rootObjectNode.set(sizeName, pageSizeNode);
            rootObjectNode.remove(pageSizeAttr);
        }
        TypeReference<?> type = new TypeReference<PageResult<?>>() {
        };
        JavaType jt = objectMapper.getTypeFactory().constructType(type);
        return objectMapper.treeToValue(root, jt);
    }
}
